home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dutil / lbmake.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  20KB  |  1,027 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  Second generation library maker.  Gets library information from lib.def
  9.  *  file in current directory
  10.  *
  11.  *  LBMAKE [keywords] [types]
  12.  *
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <sys/stat.h>
  19.  
  20. #ifdef AMIGA
  21. #include <lists.h>
  22. #include <exec/types.h>
  23. #include <dos/dos.h>
  24. #include <clib/dos_protos.h>
  25. #include <clib/exec_protos.h>
  26. #include <clib/alib_protos.h>
  27. #include <lib/version.h>
  28. #else
  29. #include <suplib/all.h>
  30. #include <include/lib/version.h>
  31. #endif
  32.  
  33. #define arysize(ary)    (sizeof(ary)/sizeof((ary)[0]))
  34.  
  35. #define KT_TYPE     0
  36. #define KT_LIBRARY  1
  37. #define KT_OBJECT   3
  38. #define KT_ALTTREE  4
  39. #define KT_OPTION   5
  40.  
  41. typedef struct Node Node;
  42. typedef struct List List;
  43. typedef struct FileInfoBlock FileInfoBlock;
  44.  
  45. typedef struct KeyNode {
  46.     Node    kn_Node;
  47.     char    *kn_Data;
  48.     char    *kn_Obj;        /*    file list only            */
  49.     char    *kn_Aux;        /*    file list only            */
  50.     short   kn_Option;        /*    -1 loose, 0 ignore, 1 use   */
  51.     short   kn_Flags;
  52. } KeyNode;
  53.  
  54. #define KF_COMPILED    0x0001
  55. #define KF_ERROR    0x0002
  56.  
  57. typedef struct CmdNode {
  58.     char    *cn_Name;        /*    name of command */
  59.     short   cn_Args;        /*    number of args    */
  60.     short   cn_Id;
  61.     int     (*cn_Func)(short, char **, short, long);
  62. } CmdNode;
  63.  
  64. void    help(int);
  65. KeyNode *FindKeyNode(KeyNode *, char *);
  66. KeyNode *FindOptionNode(KeyNode *, char *);
  67. int    CompileStuff(KeyNode *);
  68. int    JoinStuff(KeyNode *, int);
  69. int    ScanLibDefFile(void);
  70. int    ProcessCommandLine(int, char *, long);
  71. int    ProcessFileLine(int, char *, long);
  72. KeyNode* AllocKeyNode(char *, char *, char *, char *);
  73.  
  74. int    CmdAddKey(short, char **, short, long);
  75. int    CmdType(short, char **, short, long);
  76. int    CmdDefTree(short, char **, short, long);
  77.  
  78. int    Assemble(char *, char *);
  79. int    AssembleA68(char *, char *);
  80. int    FDToLib(char *, char *, char *);
  81. int    Compile(char *, char *);
  82.  
  83. int    strreplace(char *, char *, char *);
  84.  
  85. int    CompareTimeStamps(char *, char *);
  86. void    CreateDirPath(char *);
  87. char    *FillName(char *, char **, char *);
  88. void    DicePrefix(char *, char *, char *);
  89.  
  90. #ifdef LATTICE
  91. void    *GetHead(List *);
  92. void    *GetSucc(Node *);
  93. #endif
  94.  
  95. CmdNode CmdAry[] = {
  96.     {    "Objects",  2,  KT_OBJECT , CmdAddKey   },
  97.     {    "Library",  2,  KT_LIBRARY, CmdAddKey   },
  98.     {    "Type"   ,  -1, KT_TYPE   , CmdType     },
  99.     {    "DefTree",  1,  0         , CmdDefTree  },
  100.     {    "AltTree",  2,  KT_ALTTREE, CmdAddKey   },
  101.     {    "Option",   -1, KT_OPTION , CmdAddKey   }
  102. };
  103.  
  104. List    KeyList;
  105. List    FileList;
  106. char    CompilerName[64];
  107. char    FDToLibName[64];
  108. char    FlagsBuf[256];
  109. char    TypeBuf[256];
  110. char    DefTree[256];
  111. char    TmpBuf[8192];
  112. char    LastPath[256];
  113.  
  114. short    DoNotExecute;
  115.  
  116. int _DiceCacheEnable = 1;
  117.  
  118. #ifdef _DCC
  119. IDENT("lbmake",".3");
  120. DCOPYRIGHT;
  121. #endif
  122.  
  123. int
  124. main(int ac, char **av)
  125. {
  126.     short i;
  127.     short j;
  128.     int r = 0;
  129.  
  130.     NewList(&KeyList);
  131.     NewList(&FileList);
  132.  
  133.     DicePrefix(CompilerName, av[0], "dcc");
  134.     DicePrefix(FDToLibName, av[0], "fdtolib");
  135.  
  136.     if (ac == 1)
  137.     help(0);
  138.  
  139.     if (ScanLibDefFile() < 0)
  140.     help(10);
  141.  
  142.     for (i = 1; i < ac; ++i) {
  143.     char *ptr = av[i];
  144.     short option;
  145.     KeyNode *kn;
  146.  
  147.     switch(*ptr) {
  148.     case '-':
  149.         if (strcmp(ptr, "-n") == 0) {
  150.         DoNotExecute = 1;
  151.         continue;
  152.         }
  153.         option = -1;
  154.         ++ptr;
  155.         break;
  156.     case '+':
  157.         ++ptr;
  158.     default:
  159.         option = 1;
  160.         break;
  161.     }
  162.     for (kn = NULL, j = 0; (kn = FindKeyNode(kn, ptr)) != NULL; ++j)
  163.         kn->kn_Option = option;
  164.     for (kn = NULL; (kn = FindOptionNode(kn, ptr)) != NULL; ++j) {
  165.         if (kn->kn_Option == 0)
  166.         kn->kn_Option = option;
  167.     }
  168.     if (j == 0) {
  169.         printf("Unable to find symbol %s\n", ptr);
  170.         r = 10;
  171.     }
  172.     }
  173.  
  174.     /*
  175.      *    Handle compilation flags
  176.      *    Handle alternate object tree
  177.      *    Select compiler
  178.      */
  179.  
  180.     {
  181.     KeyNode *kn;
  182.     for (kn = GetHead(&KeyList); kn; kn = GetSucc(&kn->kn_Node)) {
  183.         if (kn->kn_Option <= 0)
  184.         continue;
  185.  
  186.         switch(kn->kn_Node.ln_Type) {
  187.         case KT_TYPE:
  188.         strcat(FlagsBuf, kn->kn_Data);
  189.         strcat(FlagsBuf, " ");
  190.         strcat(TypeBuf, kn->kn_Node.ln_Name);
  191.         break;
  192.         case KT_ALTTREE:
  193.         strcpy(DefTree, kn->kn_Data);
  194.         break;
  195.         default:
  196.         break;
  197.         }
  198.     }
  199.     }
  200.  
  201.     /*
  202.      *    Create destination tree
  203.      */
  204.  
  205.     sprintf(TmpBuf, DefTree, TypeBuf);
  206.     CreateDirPath(TmpBuf);
  207.  
  208.     /*
  209.      *    Scan for objects to create and libraries to make
  210.      */
  211.  
  212.     {
  213.     KeyNode *kn;
  214.     for (kn = GetHead(&KeyList); r == 0 && kn; kn = GetSucc(&kn->kn_Node)) {
  215.         if (kn->kn_Option <= 0)
  216.         continue;
  217.  
  218.         switch(kn->kn_Node.ln_Type) {
  219.         case KT_OBJECT:
  220.         case KT_LIBRARY:
  221.         r = CompileStuff(kn);    /*  < 0 error, == 0 need to link, 1 no work */
  222.         if (r >= 0 && DoNotExecute == 0)
  223.             r = JoinStuff(kn, r);
  224.         break;
  225.         default:
  226.         break;
  227.         }
  228.         if (r < 0)
  229.         break;
  230.     }
  231.     }
  232.     if (r < 0)
  233.     r = 20;
  234.     return(r);
  235. }
  236.  
  237. void
  238. help(int code)
  239. {
  240.     puts("LBMAKE [keywords types]");
  241.     exit(code);
  242. }
  243.  
  244. KeyNode *
  245. FindKeyNode(kn, name)
  246. KeyNode *kn;
  247. char *name;
  248. {
  249.     for (kn = ((kn) ? GetSucc(&kn->kn_Node) : GetHead(&KeyList)); kn; kn = GetSucc(&kn->kn_Node)) {
  250.     if (stricmp(name, kn->kn_Node.ln_Name) == 0)
  251.         break;
  252.     }
  253.     return(kn);
  254. }
  255.  
  256. KeyNode *
  257. FindOptionNode(kn, name)
  258. KeyNode *kn;
  259. char *name;
  260. {
  261.     short len = strlen(name);
  262.  
  263.     for (kn = ((kn) ? GetSucc(&kn->kn_Node) : GetHead(&FileList)); kn; kn = GetSucc(&kn->kn_Node)) {
  264.     char *ptr;
  265.  
  266.     for (ptr = kn->kn_Data; *ptr; ++ptr) {
  267.         if (*ptr == '+' || *ptr == '-') {
  268.         short l2;
  269.         {
  270.             short c;
  271.             for (l2 = 0; (c = ptr[l2]) != 0; ++l2) {
  272.             if (c == ' ' || c == '\t' || c == '\n')
  273.                 break;
  274.             }
  275.         }
  276.         if (len == l2 - 1 && strnicmp(ptr + 1, name, len) == 0) {
  277.             if (*ptr == '-')
  278.             kn->kn_Option = -1;
  279.             return(kn);
  280.         }
  281.         }
  282.     }
  283.     }
  284.     return(NULL);
  285. }
  286.  
  287. /*
  288.  *  Compile a library or object group, scan file list for files to do
  289.  *  things to.    Base the action on their tailer:
  290.  *
  291.  *    .a    assemble with DAS
  292.  *    .asm    assemble with DAS
  293.  *    .a68    assemble with A68K
  294.  *    .fd    generate using FDTOLIB
  295.  *    .lib    copy
  296.  *    .o    copy
  297.  *    .c    compile
  298.  *    <other> error
  299.  */
  300.  
  301. int
  302. CompileStuff(kn)
  303. KeyNode *kn;
  304. {
  305.     KeyNode *fn;
  306.     char *ptr;
  307.     char buf[128];
  308.     char obj[128];
  309.     int r = 1;
  310.  
  311.     printf("Compile Stuff %s: %s\n", kn->kn_Node.ln_Name, kn->kn_Data);
  312.  
  313.     sprintf(buf, "+%s", kn->kn_Node.ln_Name);
  314.  
  315.     for (fn = GetHead(&FileList); r >= 0 && fn; fn = GetSucc(&fn->kn_Node)) {
  316.     if (fn->kn_Option <= 0)
  317.         continue;
  318.     if (strstr(fn->kn_Data, buf) == NULL)
  319.         continue;
  320.  
  321.     {
  322.         int n;
  323.  
  324.         if (strchr(fn->kn_Obj, ':'))
  325.         n = 0;
  326.         else
  327.         n = sprintf(obj, DefTree, TypeBuf);
  328.         strcpy(obj + n, fn->kn_Obj);
  329.  
  330.         if ((ptr = strrchr(obj, '/')) != NULL) {
  331.         *ptr = 0;
  332.         if (strcmp(obj, LastPath) != 0) {
  333.             CreateDirPath(obj);
  334.             strcpy(LastPath, obj);
  335.         }
  336.         *ptr = '/';
  337.         }
  338.     }
  339.  
  340.     /*
  341.      *  check timestamp. returns -1, 0, 1 as in strcmp(), but also returns
  342.      *  -1 if either file does not exist
  343.      */
  344.  
  345.     if (CompareTimeStamps(obj, fn->kn_Node.ln_Name) < 0) {
  346.         if (r > 0)
  347.         r = 0;
  348.  
  349.         if ((ptr = strrchr(fn->kn_Node.ln_Name, '.')) != NULL) {
  350.         if (stricmp(ptr, ".a") == 0 || stricmp(ptr, ".asm") == 0)
  351.             r = Assemble(fn->kn_Node.ln_Name, obj);
  352.         else if (stricmp(ptr, ".a68") == 0)
  353.             r = AssembleA68(fn->kn_Node.ln_Name, obj);
  354.         else if (stricmp(ptr, ".fd") == 0)
  355.             r = FDToLib(fn->kn_Node.ln_Name, obj, fn->kn_Aux);
  356.         else if (stricmp(ptr, ".lib") == 0 || stricmp(ptr, ".o") == 0)
  357.             r = 0;
  358.         else
  359.             r = Compile(fn->kn_Node.ln_Name, obj);
  360.         } else {
  361.         r = Compile(fn->kn_Node.ln_Name, obj);
  362.         }
  363.  
  364.         /*
  365.          *    If an error occured quit out
  366.          */
  367.  
  368.         if (r > 5)
  369.         r = -r;
  370.         if (r < 0)
  371.         break;
  372.     }
  373.     }
  374.     return(r);
  375. }
  376.  
  377. /*
  378.  *  JoinStuff()
  379.  *
  380.  *  join objects into the destination library
  381.  */
  382.  
  383. int
  384. JoinStuff(kn, need)
  385. KeyNode *kn;
  386. int need;
  387. {
  388.     KeyNode *fn;
  389.     FILE *fi = NULL;
  390.     FILE *fj;
  391.     char buf[128];
  392.     static char src[128];
  393.     static char dst[128];
  394.     int r = 0;
  395.  
  396.     /*
  397.      *    compute library name
  398.      */
  399.  
  400.     if (kn->kn_Node.ln_Type == KT_LIBRARY) {
  401.     sprintf(buf, kn->kn_Data, TypeBuf);
  402.     if (need > 0 && (fi = fopen(buf, "r"))) {
  403.         printf("UpToDate: %s\n", buf);
  404.         fclose(fi);
  405.         return(0);
  406.     }
  407.     if ((fi = fopen(buf, "w")) != NULL) {
  408.         printf("Create %s\n", buf);
  409.     } else {
  410.         printf("Unable to create %s\n", buf);
  411.         return(-1);
  412.     }
  413.     }
  414.  
  415.     /*
  416.      *    append object modules
  417.      */
  418.  
  419.     sprintf(buf, "+%s", kn->kn_Node.ln_Name);
  420.     for (fn = GetHead(&FileList); r == 0 && fn; fn = GetSucc(&fn->kn_Node)) {
  421.     if (fn->kn_Option <= 0)
  422.         continue;
  423.     if (strstr(fn->kn_Data, buf) == NULL)
  424.         continue;
  425.  
  426.     {
  427.         int n;
  428.         if (strchr(fn->kn_Obj, ':'))
  429.         n = 0;
  430.         else
  431.         n = sprintf(src, DefTree, TypeBuf);
  432.         strcpy(src + n, fn->kn_Obj);
  433.     }
  434.  
  435.     if (kn->kn_Node.ln_Type == KT_OBJECT) {
  436.         char *ptr = fn->kn_Obj + strlen(fn->kn_Obj);
  437.         while (ptr >= fn->kn_Obj && *ptr != ':' && *ptr != '/')
  438.         --ptr;
  439.         sprintf(dst, kn->kn_Data, ptr + 1, TypeBuf);
  440.         if (CompareTimeStamps(dst, src) >= 0) {
  441.         printf("UpToDate: %s\n", dst);
  442.         continue;
  443.         }
  444.  
  445.         fi = fopen(dst, "w");
  446.         printf("Create %s\n", dst);
  447.     }
  448.  
  449.  
  450.     if ((fj = fopen(src, "r")) != NULL) {
  451.         long n;
  452.         while ((n = fread(TmpBuf, 1, sizeof(TmpBuf), fj)) > 0) {
  453.         if (fi) {
  454.             if (fwrite(TmpBuf, 1, n, fi) != n) {
  455.             puts("write error");
  456.             r = -1;
  457.             break;
  458.             }
  459.         }
  460.         }
  461.         fclose(fj);
  462.     } else {
  463.         printf("Unable to open %s\n", src);
  464.         r = -1;
  465.     }
  466.     if (kn->kn_Node.ln_Type == KT_OBJECT && fi) {
  467.         fclose(fi);
  468.         fi = NULL;
  469.     }
  470.     }
  471.     if (fi)
  472.     fclose(fi);
  473.     return(r);
  474. }
  475.  
  476. int
  477. ScanLibDefFile()
  478. {
  479.     FILE *fi;
  480.     char *ptr;
  481.     char buf[256];
  482.     int r = 0;
  483.     short lineNo = 0;
  484. #ifdef AMIGA
  485.     char *libDefName = getenv("LIBDEF") ? getenv("LIBDEF") : "lib.def";
  486. #else
  487.     char *libDefName = getenv("LIBDEF") ? getenv("LIBDEF") : "ulib.def";
  488. #endif
  489.  
  490.     if ((fi = fopen(libDefName, "r")) != NULL) {
  491.     while (fgets(buf, sizeof(buf), fi)) {
  492.         ++lineNo;
  493.         for (ptr = buf; *ptr == ' ' || *ptr == '\t'; ++ptr);
  494.  
  495.         if (*ptr == '\n' || *ptr == '#')
  496.         continue;
  497.  
  498.         if (*ptr == '@') {
  499.         r = ProcessCommandLine(r, ptr, lineNo);
  500.         } else {
  501.         r = ProcessFileLine(r, ptr, lineNo);
  502.         }
  503.     }
  504.     fclose(fi);
  505.     } else {
  506.     printf("Unable to open lib.def\n");
  507.     r = -1;
  508.     }
  509.     return(r);
  510. }
  511.  
  512. int
  513. ProcessCommandLine(r, cmd, line)
  514. int r;
  515. char *cmd;
  516. long line;
  517. {
  518.     static char *av[64];
  519.     short ac;
  520.  
  521.     if ((cmd = strtok(cmd + 1, " \t\n")) != NULL) {
  522.     CmdNode *cn;
  523.     for (cn = CmdAry; cn < CmdAry + arysize(CmdAry); ++cn) {
  524.         if (stricmp(cmd, cn->cn_Name) == 0)
  525.         break;
  526.     }
  527.     for (ac = 0; ac < 64 && (av[ac] = strtok(NULL, " \t\n")); ++ac)
  528.         ;
  529.     if (cn) {
  530.         if (cn->cn_Args >= 0 && ac != cn->cn_Args) {
  531.         printf("Expected %d args for %s line %ld\n", cn->cn_Args, cmd, line);
  532.         r = -1;
  533.         } else {
  534.         if (cn->cn_Func(ac, av, cn->cn_Id, line) < 0)
  535.             r = -1;
  536.         }
  537.     } else {
  538.         printf("Unknown @ command line %ld (%s)\n", line, cmd);
  539.         r = -1;
  540.  
  541.     }
  542.     } else {
  543.     printf("Bad @ command line %ld\n", line);
  544.     r = -1;
  545.     }
  546.     return(r);
  547. }
  548.  
  549. int
  550. ProcessFileLine(r, ptr, line)
  551. int r;
  552. char *ptr;
  553. long line;
  554. {
  555.     KeyNode *kn;
  556.     char *opts;
  557.     short i;
  558.     short j;
  559.     static char src[256];
  560.     static char obj[256];
  561.     static char aux[256];
  562.  
  563.     while (*ptr == ' ' || *ptr == '\t')
  564.     ++ptr;
  565.  
  566.     for (i = 0; ptr[i] && ptr[i] != ' ' && ptr[i] != '\t'; ++i) {
  567.     /*
  568.      *  Handle a comma (separator between filepathname and
  569.      *  auxillary information (e.g. library name for .fd files)
  570.      */
  571.     if (ptr[i] == ',')
  572.         break;
  573.     }
  574.  
  575.     strncpy(src, ptr, i);
  576.     src[i] = 0;
  577.  
  578.     strcpy(obj, src);
  579.  
  580.     aux[0] = 0;
  581.     if (ptr[i] == ',') {
  582.     ++i;
  583.     for (opts = ptr + i; *opts && *opts != ' ' && *opts != '\t'; ++opts)
  584.         ;
  585.     strncpy(aux, ptr + i, opts - (ptr + i));
  586.     aux[opts - (ptr + i)] = 0;
  587.     } else {
  588.     opts = ptr + i;
  589.     }
  590.     if (*opts == 0) {
  591.     printf("File Line Error, no keywords: %s", ptr);
  592.     return(-1);
  593.     }
  594.     for (; *opts == ' ' || *opts == '\t'; ++opts)
  595.     ;
  596.  
  597.     /*
  598.      *    remove '[' and ']' from source name
  599.      */
  600.  
  601.     for (i = j = 0; src[i]; ++i) {
  602.     switch(src[i]) {
  603.     case '[':
  604.     case ']':
  605.         break;
  606.     default:
  607.         src[j] = src[i];
  608.         ++j;
  609.         break;
  610.     }
  611.     }
  612.     src[j] = 0;
  613.  
  614.     /*
  615.      *    remove [path] from object name
  616.      */
  617.  
  618.  
  619.     for (ptr = strchr(obj, '['); ptr; ptr = strchr(ptr, '[')) {
  620.     char *p2;
  621.     if ((p2 = strchr(ptr, ']')) != NULL) {
  622.         movmem(p2 + 1, ptr, strlen(p2));
  623.     } else {
  624.         printf("No matching ']' on line %ld\n", line);
  625.         return(-1);
  626.     }
  627.     }
  628.  
  629.     /*
  630.      *    modify tail to .o if not already a .lib or .o
  631.      */
  632.  
  633.     if ((ptr = strrchr(obj, '.')) != NULL) {
  634.     if (stricmp(ptr, ".lib") != 0 && stricmp(ptr, ".o") != 0)
  635.         strcpy(ptr, ".o");
  636.     } else {
  637.     strcat(ptr, ".o");
  638.     }
  639.  
  640.     kn = AllocKeyNode(src, opts, obj, (aux[0] ? aux : NULL));
  641.  
  642.     AddTail(&FileList, &kn->kn_Node);
  643.  
  644.     return(r);
  645. }
  646.  
  647. int
  648. CmdAddKey(short ac, char **av, short id, long line)
  649. {
  650.     KeyNode *kn = AllocKeyNode(av[0], av[1], NULL, NULL);
  651.     kn->kn_Node.ln_Type = id;
  652.     AddTail(&KeyList, &kn->kn_Node);
  653.     return(0);
  654. }
  655.  
  656. int
  657. CmdType(short ac, char **av, short id, long line)
  658. {
  659.     short i;
  660.  
  661.     if (ac == 0) {
  662.     printf("Expected type designator line %ld\n", line);
  663.     return(-1);
  664.     }
  665.     for (i = 1, TmpBuf[0] = 0; i < ac; ++i) {
  666.     if (i > 1)
  667.         strcat(TmpBuf, " ");
  668.     strcat(TmpBuf, av[i]);
  669.     }
  670.     av[1] = TmpBuf;
  671.     return(CmdAddKey(ac, av, id, line));
  672. }
  673.  
  674. int
  675. CmdDefTree(short ac, char **av, short id, long line)
  676. {
  677.     strcpy(DefTree, av[0]);
  678.     return(0);
  679. }
  680.  
  681. KeyNode *
  682. AllocKeyNode(name1, name2, objName, auxName)
  683. char *name1;
  684. char *name2;
  685. char *objName;
  686. char *auxName;
  687. {
  688.     static char   *AlBuf;
  689.     static long   AlBytes;
  690.     KeyNode *kn;
  691.     long bytes = sizeof(KeyNode) + 2 + strlen(name1) + strlen(name2);
  692.     char *fillPtr;
  693.  
  694.     if (objName)
  695.     bytes += strlen(objName) + 1;
  696.     if (auxName)
  697.     bytes += strlen(auxName) + 1;
  698.  
  699.     bytes = (bytes + 3) & ~3;
  700.  
  701.     if (bytes > AlBytes) {
  702.     AlBuf = malloc(4096);
  703.     if (AlBuf == NULL) {
  704.         puts("malloc failed");
  705.         exit(20);
  706.     }
  707.     AlBytes = 4096;
  708.     setmem(AlBuf, 4096, 0);
  709.     }
  710.     kn = (KeyNode *)AlBuf;
  711.     fillPtr = FillName((char *)(kn + 1), &kn->kn_Node.ln_Name, name1);
  712.     fillPtr = FillName(fillPtr, &kn->kn_Data, name2);
  713.     fillPtr = FillName(fillPtr, &kn->kn_Obj, objName);
  714.     fillPtr = FillName(fillPtr, &kn->kn_Aux, auxName);
  715.     AlBuf += bytes;
  716.     AlBytes -= bytes;
  717.     return(kn);
  718. }
  719.  
  720. char *
  721. FillName(fillPtr, pptr, name)
  722. char *fillPtr;
  723. char **pptr;
  724. char *name;
  725. {
  726.     if (name) {
  727.     strcpy(fillPtr, name);
  728.     *pptr = fillPtr;
  729.     fillPtr += strlen(name) + 1;
  730.     } else {
  731.     *pptr = NULL;
  732.     }
  733.     return(fillPtr);
  734. }
  735.  
  736. /*
  737.  *  Compile, Assemble, Generate
  738.  *
  739.  */
  740.  
  741. int
  742. Assemble(srcFile, objFile)
  743. char *srcFile;
  744. char *objFile;
  745. {
  746.     long r;
  747.     char buf[256];
  748.  
  749.     sprintf(buf, "%s %s -o %s -c", CompilerName, srcFile, objFile);
  750.     puts(buf);
  751.     fflush(stdout);    /* SAS/C */
  752.  
  753.     r = 0;
  754.     if (DoNotExecute == 0)
  755.     r = system(buf);
  756.     return(r);
  757. }
  758.  
  759.  
  760. int
  761. AssembleA68(srcFile, objFile)
  762. char *srcFile;
  763. char *objFile;
  764. {
  765.  
  766.     /* XXX */
  767.     return(-1);
  768. }
  769.  
  770.  
  771. int
  772. FDToLib(srcFile, objFile, aux)
  773. char *srcFile;
  774. char *objFile;
  775. char *aux;
  776. {
  777.     long r;
  778.     char buf[256];
  779.     char hfile[256];
  780.  
  781.     /*
  782.      *    locate header file (only required for registered-args tag generation)
  783.      */
  784.  
  785.     strcpy(hfile, srcFile);
  786.     if (strreplace(hfile, "_lib.fd", "_protos.h") < 0) {
  787.     printf("FD file not in *_lib.fd format: %s\n", srcFile);
  788.     return(-1);
  789.     }
  790.     if (strreplace(hfile, "/fd/", "/clib/") < 0)
  791.     strreplace(hfile, ":fd/", ":clib/");
  792.  
  793.     r = sprintf(buf, "%s %s -h %s -o %s %s", FDToLibName, srcFile, hfile, objFile, FlagsBuf);
  794.     if (aux)
  795.     sprintf(buf + r, " -auto %s", aux);
  796.     puts(buf);
  797.     fflush(stdout);    /* SAS/C */
  798.  
  799.     r = 0;
  800.     if (DoNotExecute == 0)
  801.     r = system(buf);
  802.  
  803.     return(r);
  804. }
  805.  
  806. int
  807. Compile(srcFile, objFile)
  808. char *srcFile;
  809. char *objFile;
  810. {
  811.     long r;
  812.     char buf[256];
  813.  
  814.     sprintf(buf, "%s %s -o %s %s -c", CompilerName, srcFile, objFile, FlagsBuf);
  815.     puts(buf);
  816.     fflush(stdout);    /* SAS/C */
  817.  
  818.     r = 0;
  819.     if (DoNotExecute == 0)
  820.     r = system(buf);
  821.  
  822.     return(r);
  823. }
  824.  
  825. #ifndef LATTICE
  826.  
  827. int
  828. CompareTimeStamps(name1, name2)
  829. char *name1;
  830. char *name2;
  831. {
  832.     struct stat stat1;
  833.     struct stat stat2;
  834.     long r = -1;
  835.  
  836.     if (stat(name1, &stat1) == 0) {
  837.     if (stat(name2, &stat2) == 0) {
  838.         if (stat1.st_mtime >= stat2.st_mtime) {
  839.         if (stat1.st_mtime == stat2.st_mtime) {
  840.             r = 0;
  841.         } else {
  842.             r = 1;
  843.         }
  844.         }
  845.     }
  846.  
  847.     }
  848.     return(r);
  849. }
  850.  
  851. #ifdef NOTDEF
  852.  
  853. int
  854. CompareTimeStamps(name1, name2)
  855. char *name1;
  856. char *name2;
  857. {
  858.     long lock1;
  859.     long lock2;
  860.     __aligned FileInfoBlock fib1;
  861.     __aligned FileInfoBlock fib2;
  862.     int r = -1;
  863.  
  864.     if (lock1 = Lock(name1, SHARED_LOCK)) {
  865.     if (Examine(lock1, &fib1)) {
  866.         if (lock2 = Lock(name2, SHARED_LOCK)) {
  867.         if (Examine(lock2, &fib2)) {
  868.             if (fib1.fib_Date.ds_Days >= fib2.fib_Date.ds_Days) {
  869.             if (fib1.fib_Date.ds_Days == fib2.fib_Date.ds_Days) {
  870.                 if (fib1.fib_Date.ds_Minute >= fib2.fib_Date.ds_Minute) {
  871.                 if (fib1.fib_Date.ds_Minute == fib2.fib_Date.ds_Minute) {
  872.                     if (fib1.fib_Date.ds_Tick == fib2.fib_Date.ds_Tick)
  873.                     r = 0;
  874.                     else if (fib1.fib_Date.ds_Tick > fib2.fib_Date.ds_Tick)
  875.                     r = 1;
  876.                 } else {
  877.                     r = 1;
  878.                 }
  879.                 }
  880.             } else {
  881.                 r = 1;
  882.             }
  883.             }
  884.         }
  885.         UnLock(lock2);
  886.         }
  887.     }
  888.     UnLock(lock1);
  889.     }
  890.     return(r);
  891. }
  892. #endif
  893.  
  894. #else
  895.  
  896. int
  897. CompareTimeStamps(name1, name2)
  898. char *name1;
  899. char *name2;
  900. {
  901.     long lock1;
  902.     long lock2;
  903.     FileInfoBlock *fib1 = malloc(sizeof(FileInfoBlock));
  904.     FileInfoBlock *fib2 = malloc(sizeof(FileInfoBlock));
  905.     int r = -1;
  906.  
  907.     if (lock1 = Lock(name1, SHARED_LOCK)) {
  908.     if (Examine(lock1, fib1)) {
  909.         if (lock2 = Lock(name2, SHARED_LOCK)) {
  910.         if (Examine(lock2, fib2)) {
  911.             if (fib1->fib_Date.ds_Days >= fib2->fib_Date.ds_Days) {
  912.             if (fib1->fib_Date.ds_Days == fib2->fib_Date.ds_Days) {
  913.                 if (fib1->fib_Date.ds_Minute >= fib2->fib_Date.ds_Minute) {
  914.                 if (fib1->fib_Date.ds_Minute == fib2->fib_Date.ds_Minute) {
  915.                     if (fib1->fib_Date.ds_Tick == fib2->fib_Date.ds_Tick)
  916.                     r = 0;
  917.                     else if (fib1->fib_Date.ds_Tick > fib2->fib_Date.ds_Tick)
  918.                     r = 1;
  919.                 } else {
  920.                     r = 1;
  921.                 }
  922.                 }
  923.             } else {
  924.                 r = 1;
  925.             }
  926.             }
  927.         }
  928.         UnLock(lock2);
  929.         }
  930.     }
  931.     UnLock(lock1);
  932.     }
  933.     free(fib1);
  934.     free(fib2);
  935.     return(r);
  936. }
  937.  
  938. void *
  939. GetHead(list)
  940. List *list;
  941. {
  942.     if (list->lh_Head->ln_Succ)
  943.     return(list->lh_Head);
  944.     return(NULL);
  945. }
  946.  
  947. void *
  948. GetSucc(node)
  949. Node *node;
  950. {
  951.     if (node->ln_Succ->ln_Succ)
  952.     return(node->ln_Succ);
  953.     return(NULL);
  954. }
  955.  
  956. #endif
  957.  
  958. void
  959. CreateDirPath(buf)
  960. char *buf;
  961. {
  962.     short n;
  963.     char *p2;
  964.  
  965.     if ((n = strlen(buf)) && buf[n-1] == '/')
  966.     buf[--n] = 0;
  967.  
  968.     if (CompareTimeStamps(buf, buf) != 0) {
  969. #ifdef AMIGA
  970.     if (mkdir(buf) < 0) {
  971. #else
  972.     if (mkdir(buf, 0777) < 0) {
  973. #endif
  974.         if ((p2 = strrchr(buf, '/')) != NULL) {
  975.         *p2 = 0;
  976.         CreateDirPath(buf);
  977.         *p2 = '/';
  978. #ifdef AMIGA
  979.         mkdir(buf);
  980. #else
  981.         mkdir(buf, 0777);
  982. #endif
  983.         }
  984.     }
  985.     }
  986. }
  987.  
  988. int
  989. strreplace(buf, findStr, repStr)
  990. char *buf;
  991. char *findStr;
  992. char *repStr;
  993. {
  994.     char *ptr;
  995.  
  996.     if ((ptr = strstr(buf, findStr)) != NULL) {
  997.     short l1 = strlen(findStr);
  998.     short l2 = strlen(repStr);
  999.  
  1000.     if (l1 < l2)
  1001.         movmem(ptr, ptr + (l2 - l1), strlen(ptr) + 1);
  1002.     else if (l1 > l2)
  1003.         movmem(ptr, ptr - (l1 - l2), strlen(ptr) + 1);
  1004.     strncpy(ptr, repStr, l2);
  1005.     return(0);
  1006.     } else {
  1007.     return(-1);
  1008.     }
  1009. }
  1010.  
  1011. void
  1012. DicePrefix(char *buf, char *av0, char *app)
  1013. {
  1014.     char *ptr;
  1015.     short n = 0;
  1016.  
  1017.     for (ptr=av0+strlen(av0); ptr >= av0 && *ptr != '/' && *ptr != ':'; --ptr)
  1018.     ;
  1019.     ++ptr;
  1020.     if ((av0 = strchr(ptr, '_')) != NULL) {
  1021.     n = av0 - ptr + 1;
  1022.     strncpy(buf, ptr, n);
  1023.     }
  1024.     strcpy(buf + n, app);
  1025. }
  1026.  
  1027.